import { _decorator, Component, Node, loader, Prefab, Vec3 } from "cc";
import { Car } from "./Car";
import { RoadPoint } from "./RoadPoint";
import { PoolManager } from "../data/PoolManager";
import { CustomerEventListener } from "../data/CustomerEventListener";
import { Constants } from "../data/Constants";
const { ccclass, property } = _decorator;

@ccclass("CarManager")
export class CarManager extends Component {

    @property({ type: Car, tooltip: '玩家小车' })
    mainCar: Car = null;

    @property({ type: Node, tooltip: '相机' })
    camera: Node = null;

    @property({ type: Vec3, tooltip: '照相机位置' })
    cameraPos = new Vec3(0, 8, 8);

    @property({ type: Number, tooltip: '照相机角度' })
    cameraRotation = -45;

    private currPath: Node[] = [];
    private aiCars: Car[] = [];

    start(): void {
        CustomerEventListener.on(Constants.EventName.GAME_OVER, this.gameOver, this);
    }

    public reset(points: Node[]) {
        if (points.length <= 0) {
            console.log('there is no point in this map')
            return;
        }
        this.recycleAllAICar();
        this.currPath = points;
        this.createMainCar(points[0]);
        this.startSchedule();
    }


    public controlMoving(isRunning: boolean): void {
        if (isRunning) {
            this.mainCar.startRunning();
        } else {
            this.mainCar.stopRunning();
        }
    }

    private createMainCar(point: Node): void {
        this.mainCar.setEntry(point, true);
        this.mainCar.setCamera(this.camera, this.cameraPos, this.cameraRotation);
    }

    private startSchedule(): void {
        for (let i = 1; i < this.currPath.length; i++) {
            const path = this.currPath[i];
            const roadPoint = path.getComponent(RoadPoint);
            roadPoint.startSchedule(this.createEnemy.bind(this));
        }
    }

    private stopSchedule(): void {
        for (let i = 1; i < this.currPath.length; i++) {
            const path = this.currPath[i];
            const roadPoint = path.getComponent(RoadPoint);
            roadPoint.stopSchedule();
        }
    }

    private createEnemy(road: RoadPoint, carId: string): void {

        const self = this;

        loader.loadRes(`car/car${carId}`, Prefab, (err: any, prefab: Prefab) => {
            if (err) {
                console.warn(err);
                return;
            }

            const car = PoolManager.getNode(prefab, self.node);
            // console.log('createEnemy, car from pool: ' + car);

            const carComp = car.getComponent(Car);
            this.aiCars.push(carComp);
            carComp.setEntry(road.node);
            carComp.maxSpeed = road.speed;
            carComp.startRunning();
            carComp.moveAfterFinished(this.recycleCar.bind(this));
        });

    }

    private recycleCar(car: Car): void {
        const index = this.aiCars.indexOf(car);
        console.log('recycleCar, index: ' + index);
        if (index > -1) {
            PoolManager.setNode(car.node);
            this.aiCars.splice(index, 1);
        }
    }

    private recycleAllAICar(): void {
        for (let i = 0; i < this.aiCars.length; i++) {
            const car = this.aiCars[i];
            PoolManager.setNode(car.node);
        }
        this.aiCars.length = 0;
    }

    private gameOver(): void {
        this.stopSchedule();
        this.mainCar.stopImmediately();
        this.camera.setParent(this.node.parent, true);
        for (let i = 0; i < this.aiCars.length; i++) {
            const car = this.aiCars[i];
            car.stopImmediately();
        }
    }

}